import { Injectable, Type } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import {
  CanActivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  UrlTree,
  Router,
} from '@angular/router';
import { DialogService } from 'ng-devui/modal';
import { LoadingService } from 'ng-devui/loading';
import { Observable } from 'rxjs';
import { QueryParams } from './interface/manage';

export interface questionnaireObject {
  type: string; //表单类型
  value?: '';
  values?: Array<assetsInfoObject>;
  serialNumber: string; //序号
  placeholder?: string;
  currVal?: string;
  required: boolean; //是否必填
  name: string;
  questionStem: string; //题干
  answerOptions?: Array<assetsInfoObject>; //答案选项
}

export interface tabListObject {
  title: string;
  subTitle: string;
}

export interface myCollectionsObject {
  token: string;
  numberNo: string;
  name: string;
  imgSrc: string;
  tabList: Array<tabListObject>;
  assetId: string;
}

export interface SourceType {
  block_id: string;
  tx_id: string;
  time: string;
}

export interface bottomLinkObject {
  url: string;
  name: string;
}

export interface homeBottomDataObject {
  linkList: bottomLinkObject[];
  title: string;
}

export interface assetsInfoObject {
  name?: string;
  id?: string | number;
  value: string;
  title?: string;
}

export interface homeDigitalInfoObject {
  title: string;
  leftText: string[];
  rightPic: string;
  subTitle?: string;
}

export interface tabListObj {
  zhTitle: string;
  enTitle: string;
  imgSrc: String;
  artists: String;
  descText: String;
}

export interface assetsSourceType {
  blockId: string;
  txId: string;
  time: Date;
}

export interface navListObject {
  name: string;
  value: string;
  link: string;
}
export interface galleryInfoObject {
  collection: string;
  id: string;
  picture: string;
  owner: string;
  time: string;
}

@Injectable()
export class AuthGuardService implements CanActivate {
  i18nValues: any;
  headers: HttpHeaders = new HttpHeaders();
  timer: any = null;
  token: string = '';
  userUid: string = '';
  showLoading: any;
  urlIncludeCode: string = '';
  isHrefExistCode: boolean = false;
  currentUrl: string = '';

  constructor(
    private loadingService: LoadingService,
    private http: HttpClient,
    private dialogService: DialogService
  ) { }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {
    if (!window.location.href.includes('code')) {
      localStorage.setItem('currUrlKey', window.location.href);
      this.isHrefExistCode = false;
    } else {
      this.urlIncludeCode = window.location.href;
      this.isHrefExistCode = true;
    }
    return true;
  }

  //查询用户所有藏品
  queryUserAllAssets(object: QueryParams): Observable<any> {
    const obj = {};
    Object.keys(object).forEach((item) => {
      obj[item] = object[item];
    });
    return this.http.get('v1/assets/get', { params: obj });
  }

  //查询最近的交易笔数
  queryRecentTransactionCount(params: string): Observable<any> {
    return this.http.get('v1/transactions/list', {
      params: {
        number: params,
      },
    });
  }

  //查询区块链概要信息
  queryBlockchainSummaryInfo(): Observable<any> {
    return this.http.get('v1/store/blocks/summary');
  }

  //查询藏品链上详情
  queryAssetsDetail(id: string): Observable<any> {
    return this.http.get('v1/assets/verify', {
      params: {
        id,
      },
    });
  }

  //查询我的藏品详情
  getAssetsDetail(userId: number, collectionIndex: string, tokenId: string): Observable<any> {
    return this.http.get('v1/assets/detail', {
      params: {
        userId, collectionIndex, tokenId
      }
    })
  }

  //藏品转赠
  assetsTranfer(userId: number, assetId: string, address: string): Observable<any> {
    return this.http.post('/v1/assets/transfer', {
      userId: userId,
      assetId: assetId,
      receiverAddress: address
    })
  }

  //是否认证登录
  isAuthLogin(display: string, redirect_uri: string): Observable<any> {
    return this.http.get('v1/sso/login', {
      params: {
        display,
        redirect_uri,
      },
    });
  }

  //获取token
  getAccessToken(code: string, redirect_uri: string): Observable<any> {
    return this.http.get('v1/sso/accesstoken', {
      params: {
        code,
        redirect_uri,
      },
    });
  }

  //获取区块链类型
  getBlockChainType(): Observable<any> {
    return this.http.get('/v1/blockchaintype');
  }

  //获取域账户信息
  getDomainAccountInfo(): Observable<any> {
    return this.http.get('v1/sso/user', {
      headers: this.headers.set('X-Auth-Token', this.token),
    });
  }

  //获取画廊数据
  getGalleryInfo(number: string): Observable<any> {
    return this.http.get('v1/assets/list', {
      params: {
        number,
      },
    });
  }

  // 获取首页藏品列表
  collectionDetail(object: QueryParams): Observable<any> {
    const obj = {};
    Object.keys(object).forEach((item) => {
      if (object[item]) {
        obj[item] = object[item];
      }
    });
    return this.http.get('v1/collection/detail', { params: obj });
  }

  invokingIsAuthLogin(display: string, hrefStr: string) {
    this.showLoading = this.loadingService.open();
    this.isAuthLogin(display, hrefStr).subscribe(
      (succRes) => {
        if (typeof succRes === 'string') {
          window.location.replace(succRes);
        }
        this.showLoading.loadingInstance.close();
      },
      (errRes) => {
        const MSG = errRes?.error?.message;
        this.showLoading.loadingInstance.close();
        this.showModalPanel(
          'warning',
          MSG ? this.errorMsgReflect[MSG] : '服务端错误'
        );
      }
    );
  }

  //初始化页面
  initPageInfo(fn?: Function): void {
    this.showLoading = this.loadingService.open();
    const str = this.urlIncludeCode.split('code=')[1];
    const code = str.split('&')[0];
    this.getAccessToken(
      code,
      localStorage.getItem('currUrlKey') || window.location.href
    ).subscribe(
      (succRes: any) => {
        if (succRes.access_token) {
          this.token = succRes.access_token;
          this.invokingGetDomainAcctInfo(fn);
        } else {
          this.showLoading.loadingInstance.close();
        }
      },
      (errMes) => {
        this.showLoading.loadingInstance.close();
        const MSG = errMes?.error?.message;
        this.showModalPanel(
          'warning',
          MSG ? this.errorMsgReflect[MSG] : '服务端错误'
        );
      }
    );
  }

  invokingGetDomainAcctInfo(fn: Function) {
    this.getDomainAccountInfo().subscribe(
      (succInfoRes) => {
        if (succInfoRes.uid) {
          this.userUid = succInfoRes.uid;
          (window as any).init('1', '7beef4f0786146a48e5f28541e2b89b0', '', {
            UserAccount: '' + this.userUid + '',
            siteLang: '简体中文',
          });
          fn && fn();
        }
        this.showLoading.loadingInstance.close();
      },
      (errInfoRes) => {
        this.showLoading.loadingInstance.close();
        const MSG = errInfoRes?.error?.message;
        this.showModalPanel(
          'warning',
          MSG ? this.errorMsgReflect[MSG] : '服务端错误'
        );
      }
    );
  }

  //防抖
  debounce(func: any, delay?: number) {
    if (Object.prototype.toString.call(func) !== '[object Function]') return;
    return (() => {
      let context = this;
      let args = arguments;
      clearTimeout(this.timer);
      this.timer = setTimeout(function () {
        func.apply(context, args);
      }, delay || 500);
    })();
  }

  //弹框
  showModalPanel(
    dialogtype: string,
    content: string,
    title?: string
  ): Promise<boolean> {
    return new Promise((resolve) => {
      const results = this.dialogService.open({
        id: 'dialog-service',
        width: '300px',
        maxHeight: '600px',
        title: title || '温馨提示',
        content,
        backdropCloseable: false,
        dialogtype,
        buttons: [
          {
            cssClass: 'primary',
            text: '确定',
            handler: ($event: Event) => {
              results.modalInstance.hide();
              resolve(true);
            },
          },
        ],
      });
    });
  }

  errorCode: any = {
    '401': '未登录，或登录过期，请重新登录！',
    '403': '当前操作没有权限',
    '404': '访问资源不存在',
    default: '系统未知错误，请反馈给管理员',
  };

  //错误信息国际化映射
  errorMsgReflect: any = {
    'apply assets fail': '申请藏品失败',
    'assets have already run out': '藏品已经发完啦！',
    'assets of the user reach maximum': '您已经领取过啦！',
    'get asset fail': '查询藏品失败',
    'user not exist': '账号不存在',
    'invalid username []': '无效的用户名',
    'get asset detail fail': '查询藏品详情失败',
    'get block summary fail': '查询区块概要失败',
    'get transactions fail': '查询交易列表失败',
    'asset not exist': '藏品不存在',
    'access denied': ' 暂未获得领取权限喔！',
  };

  getErrorCode(code: string): string {
    if (Object.keys(this.errorCode).includes(code)) {
      return this.errorCode[code];
    } else {
      return this.errorCode['default'];
    }
  }

  calcDownTitlePosition(contentEle: string, downElement: string) {
    let timer = setTimeout(() => {
      let contentHeight = document.querySelector(contentEle).scrollHeight;
      let downHeight = document.querySelector(downElement).scrollHeight;
      let allHeight = document.body.clientHeight;
      let downEle = document.querySelector(downElement) as any;
      if (contentHeight + downHeight < allHeight - 20) {
        downEle.style.position = 'fixed';
        downEle.style.bottom = '20px';
      } else {
        downEle.style.position = 'static';
        downEle.style.bottom = '';
      }
      clearTimeout(timer);
      timer = null;
    }, 500);
  }
  
  formatDate(v: string, flag = true) {
    if (!v) return '';
    let date = new Date(v);
    let y = date.getFullYear();
    let MM: string | number = date.getMonth() + 1;
    MM = MM < 10 ? '0' + MM : MM;
    let d: string | number = date.getDate();
    d = d < 10 ? '0' + d : d;
    if (flag) {
      let h: string | number = date.getHours();
      h = h < 10 ? '0' + h : h;
      let m: string | number = date.getMinutes();
      m = m < 10 ? '0' + m : m;
      let s: string | number = date.getSeconds();
      s = s < 10 ? '0' + s : s;
      return y + '-' + MM + '-' + d + ' ' + h + ':' + m + ':' + s;
    } else {
      return y + '/' + MM + '/' + d;
    }
  }
}
